package com.xuzimian.demo.java.proxy.dynamic

import com.xuzimian.demo.java.proxy.ISubject
import com.xuzimian.demo.java.proxy.RealSubject
import com.xuzimian.demo.java.proxy.SubjectNoInterfaces
import java.lang.reflect.InvocationHandler
import java.lang.reflect.Method
import java.lang.reflect.Proxy
import kotlin.test.Test

class JdkProxySuccessTest {
    @Test
    fun test_success() {

        val iSubjectProxy: ISubject = Proxy.newProxyInstance(ISubject::class.java.classLoader,
                arrayOf(ISubject::class.java), JdkHandler(RealSubject())) as ISubject

        iSubjectProxy.processBusiness()
    }

    @Test
    fun test_Fail() {
        val proxy: SubjectNoInterfaces = Proxy.newProxyInstance(
                SubjectNoInterfaces::class.java.getClassLoader(),
                arrayOf(SubjectNoInterfaces::class.java),
                JdkHandler(SubjectNoInterfaces())
        ) as SubjectNoInterfaces
        proxy.processBusiness()
    }
}

class JdkHandler(private val target: Any) : InvocationHandler {
    @Throws(Throwable::class)
    override fun invoke(proxy: Any, method: Method, args: Array<Any>?): Any {
        doBefore()
        val result = method.invoke(target, *(args ?: arrayOfNulls<Any>(0)))
        doAfter()
        return result
    }

    private fun doBefore() {
        println("Before ...")
    }

    private fun doAfter() {
        println("After ...")
    }

}